package org.desktop.web.server;

import java.io.InputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.desktop.web.server.factory.ConfigurationFactory;
import org.desktop.web.server.util.RpcUtil;
import org.desktop.web.shared.domain.PageEntity;
import org.desktop.web.shared.domain.entities.User;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.sencha.gxt.data.shared.SortInfo;
import com.sencha.gxt.data.shared.loader.PagingLoadConfig;
import com.sencha.gxt.data.shared.loader.PagingLoadResult;
import com.sencha.gxt.data.shared.loader.PagingLoadResultBean;

public abstract class AbstractPagingService<Data extends Serializable> extends RemoteServiceServlet {
	

	/**
	 * Specifica il tipo di dato che dev'essere retituito alla griglia richiedente.
	 * @return
	 */
	public abstract Class<?> getType() ;

	
	public  PagingLoadResult<Data> getDatas (Map<String, String> headers,
			PagingLoadConfig loadConfig,String url) throws Exception {
		try {
			int activePage = RpcUtil.getActivePage(loadConfig);
			List<SortInfo> sorts = (List<SortInfo>) loadConfig.getSortInfo();

			StringBuilder sortUrl = RpcUtil.createSortUrl(sorts);
			String pagination = RpcUtil.createPaginationUrl(url,
					loadConfig, activePage, sortUrl);

			String token = headers.get("token");
			URL _url = new URL(pagination);
			HttpURLConnection con = RpcUtil.getUrlConnection(_url, "GET");
			con.setRequestProperty("Accept", "application/json");
			con.setRequestProperty("token", token);
			InputStream in = con.getInputStream();
			String result = IOUtils.toString(in);
			
			in.close();
			ObjectMapper map = new ObjectMapper();
//			PageEntity<User> entities = map.readValue(result,
//					new TypeReference<PageEntity<User>>() {
//					});


//			PagingLoadResultBean<User> resultBean = new PagingLoadResultBean<User>(
//					entities.getContent(), entities.getTotalElements(), entities.getNumber());
			PagingLoadResult<Data> r =  getPagingLoadResult(createPageEntity(result));
			return r;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public   PageEntity<Data> createPageEntity(String result) throws Exception{
		ObjectMapper mapper = new ObjectMapper();
		TypeFactory tf = TypeFactory.defaultInstance();

		PageEntity<Data> pe = mapper.readValue(result, tf.constructParametricType(PageEntity.class, getType()));
		return pe;
	}
	
	

	public PagingLoadResult<Data> getPagingLoadResult(PageEntity<Data> entities){
		return new PagingLoadResultBean<Data>(
				entities.getContent(), entities.getTotalElements(), entities.getNumber());
	}
}